package com.wxtech.heartbeat.server.protocol;


import java.util.Arrays;
import java.util.Date;

import org.apache.log4j.Logger;

import com.wxtech.heartbeat.model.Device;
import com.wxtech.heartbeat.model.ErrorData;
import com.wxtech.heartbeat.model.HeartBeat;
import com.wxtech.heartbeat.util.CHexConver;
import com.wxtech.heartbeat.util.DateUtil;
import com.wxtech.heartbeat.util.IntegerUtil;

import io.netty.buffer.ByteBuf;

public class HeartBeatProtocolDecoder extends Protocol {
	private static Logger logger = Logger.getLogger(HeartBeatProtocolDecoder.class);

	public HeartBeatProtocolDecoder() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public DecodeResult decode(ByteBuf buffer) {
		// TODO Auto-generated method stub
		// 0. 48个字节
		byte[] raw = new byte[HeartBeatProtocolConstant.TOTAL_LENGTH];
		buffer.getBytes(buffer.readerIndex(), raw);

		// buffer.resetReaderIndex();
		int beginIndex = buffer.readerIndex();

//		byte[] cmdType = new byte[1];
		byte[] biaoHao = new byte[2];
		byte[] deviceBytes = new byte[Device.SIZE_OF_DEVICE_ID];
		byte[] beatTime = new byte[6];
		byte[] sim = new byte[HeartBeatProtocolConstant.LENGTH_SIM];
		byte[] seriialNoBytes = new byte[HeartBeatProtocolConstant.LENGTH_SERIAL];

		HeartBeatProtocolDecodeResult pData = new HeartBeatProtocolDecodeResult();

		//1. 包的总数
		int total = buffer.getUnsignedByte(
		beginIndex + HeartBeatProtocolConstant.POS_OF_TOTAL);
		
		// 2. 验证标号
		buffer.getBytes(beginIndex + HeartBeatProtocolConstant.POS_OF_BIAOHAO, biaoHao);
		String biaoHaoString = CHexConver.byte2HexStr(biaoHao, 2);
		int biaohaoInteger = buffer.getUnsignedShortLE(beginIndex + HeartBeatProtocolConstant.POS_OF_BIAOHAO);//IntegerUtil.parseU16(biaoHao);
		logger.info("skip checking biaohao");
//		if (!HeartBeatProtocolConstant.BIAOHAO.equals(biaoHaoString)) {
//			// 标号不对，报错
//			logger.error("wrong biaohao as " + biaoHaoString + " byte=" + Arrays.toString(biaoHao));
//			pData.setValid(false);
//			pData.setErrorData(buildError(raw, ErrorData.ERROR_CODE_INVALID_BIAOHAO));
//			buffer.skipBytes(HeartBeatProtocolConstant.TOTAL_LENGTH);
//			return pData;
//		}

		// 3. 设备id u64
		logger.info("parsing device id");
		buffer.getBytes(beginIndex + HeartBeatProtocolConstant.POS_OF_DEVICE, deviceBytes);
		String deviceId = IntegerUtil.parseU64(deviceBytes);

		// 4. 时间
		logger.info("parsing time");
		buffer.getBytes(beginIndex + HeartBeatProtocolConstant.POS_OF_BEATTIME, beatTime);
		Date beatDate = DateUtil.parseDateTime(beatTime);
		if (beatDate == null) {
			// 时间不对，报错
			logger.debug("wrong date");
			pData.setValid(false);
			pData.setErrorData(buildError(raw, ErrorData.ERROR_CODE_INVALID_TIME));
			buffer.skipBytes(HeartBeatProtocolConstant.TOTAL_LENGTH);
			return pData;
		}

		// 5. sim
		logger.info("parsing simId");
		buffer.getBytes(beginIndex + HeartBeatProtocolConstant.POS_OF_SIM, sim);
		String simIdString = new String(sim);

		// 6. 表序列号
		logger.info("parsing serial");
		buffer.getBytes(beginIndex + HeartBeatProtocolConstant.POS_OF_SERIAL, seriialNoBytes);
		String serialString = IntegerUtil.parseU64(seriialNoBytes);

		// 7. CRC验证
		logger.info("skip....checking crc");
//		byte[] allData = new byte[46];
//		buffer.getBytes(beginIndex, allData);
		// ByteBuffer bb = ByteBuffer.wrap(allData);
		// int crc16 = Checksum.crc16(Checksum.CRC16_AUG_CCITT, bb);
//		int actualCrc16 = buffer.getUnsignedShort(beginIndex + 46);
//		if (!compareCrc(allData, actualCrc16)) {
//			// crc校验出错了
//			logger.error("wrong crc16 check calc=" + " received=" + actualCrc16);
//			pData.setValid(false);
//			pData.setErrorData(buildError(raw, ErrorData.ERROR_CODE_INVALID_CRC));
//			buffer.skipBytes(HeartBeatProtocolConstant.TOTAL_LENGTH);
//
//			return pData;
//		}

		// 2. 装配对象
		pData.setValid(true);
		Device d = new Device();
		d.setDevice_id(deviceId);
		pData.setDevice(d);

		HeartBeat hb = new HeartBeat();
		hb.setTotal(total);
		hb.setBiaohao(biaohaoInteger);
		hb.setDeviceId(deviceId);
		hb.setDateTime(beatDate);
		hb.setSimId(simIdString);
		hb.setSerial(serialString);
		pData.setHeartBeat(hb);

		// read bytes to avoid DecoderException:ProtocolDecoder.decode() did not
		// read anything but decoded a message.
		buffer.readBytes(raw);

		// 6. 下一步交给后面的DatabaseLogicHandler去处理数据的存储工作

		logger.info("finishing");
		return pData;
	}

	@Override
	public boolean isBufferDataEnough(ByteBuf buffer) {
		boolean enough = false;
		if (buffer.readableBytes() >= HeartBeatProtocolConstant.TOTAL_LENGTH) {
			enough = true;
		}
		return enough;
	}

}
